package com.study.kt._04project.encrypt

import java.security.KeyFactory
import java.security.KeyPairGenerator
import java.security.PrivateKey
import java.security.PublicKey
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import java.util.*
import javax.crypto.Cipher

/**
 * 常用算法：RSA
 *  1.密钥对：公钥和私钥，必须由系统生成，不同于对称加密可以使用自己定义的
 *  2.公钥加密，私钥解密；私钥加密，公钥解密(privateKey、publicKey)
 *  3.公钥互换：两个组织或者人相互交换公钥
 *  4.加密速度慢
 *
 *  加密/解密的场景：
 *   1.A有份文件使用私钥加密生成密文，B使用A的公钥解密；
 *   2.A使用B的公钥加密传输给B，B使用自己的私钥解密
 *
 */
fun main() {

    //简单的文本加密后生成的文本也很长所以安全
    val content = "hello world"
    val publicEncryptResult = RSACrypt.encryptByPublicKey(content)
    println("公钥加密结果：$publicEncryptResult")
    val privateEncryptResult = RSACrypt.encryptByPrivateKey(content)
    println("私钥加密结果：$privateEncryptResult")
}

object RSACrypt {

    val publicKey: PublicKey
    val privateKey: PrivateKey

    init {
        //生成密钥对
        //密钥对生成器
        val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
        //生成密钥对
        val keyPair = keyPairGenerator.genKeyPair()

        //返回密钥对的对象
        publicKey = keyPair.public
        privateKey = keyPair.private

        //转为String
        /**
         * MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAipBn5j50AwBWD5+jrOJQDkKcGmxqRQ0g8zsNYdJRc
         * FhrFWbAsVKjr7iyuqCp+CenSC5/0C1/hTN1QN0rv72SvGgk/n5Mcwe9SF3BLDqYc5UOj+6jXEnyr5fxLFEEtc
         * 7PsOtoGcG3GXL5x1itD/xpUjygwwwzCoorFhlddpb3GX23+5TNi96zECrC1qa+9d0t7sssYXfTIA1rMWVw4Z2
         * W+4miTCbHesAoP+8ThdAV3rd0pEAdmEX/VxnxXmfN0UfTX0soHe2sstfkGL3jBo/lQodNJiSSuhTYlOoOK/Qy
         * e6dpccUdWIgBT5fO7xyP7wKrTJ3xlUzZ3HQDDT14d3/a/wIDAQAB
         */
        val publicStr = String(Base64.getEncoder().encode(publicKey.encoded))

        /**
         * MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCKkGfmPnQDAFYPn6Os4lAOQpwabGpFDSDzOw
         * 1h0lFwWGsVZsCxUqOvuLK6oKn4J6dILn/QLX+FM3VA3Su/vZK8aCT+fkxzB71IXcEsOphzlQ6P7qNcSfKvl/Es
         * UQS1zs+w62gZwbcZcvnHWK0P/GlSPKDDDDMKiisWGV12lvcZfbf7lM2L3rMQKsLWpr713S3uyyxhd9MgDWsxZX
         * DhnZb7iaJMJsd6wCg/7xOF0BXet3SkQB2YRf9XGfFeZ83RR9NfSygd7ayy1+QYveMGj+VCh00mJJK6FNiU6g4r9
         * DJ7p2lxxR1YiAFPl87vHI/vAqtMnfGVTNncdAMNPXh3f9r/AgMBAAECggEANyUVVHqSbQdbOMiNuSYwOhykR5fS
         * Cz0YWfSsdLvhEVb+9vt3wJpk7nARIVkDi/EsD/wBffY9g+NgzLm4yYxGs5i28FmPT1BLMlutn06KkaVGsF2Gwhnj
         * 7aIIp1xvBXQTEBP/0BBaMFSjt4RBC9WmjMX4LOfUAGPQlfDuU13tZUUZjpKulgW6eBUwwvMBdb0mRdE0MH4sgUwR
         * AcO2PE5e0T+J0qq8L+9WqfH4mvtR517r85ZsXpbJGA8lYNU39eK/PRpFO8Qe4mwPbq9I8PlpAQcYc6XzopRcPe8U//
         * JM72k3F8VmgYbT532GMZEvWZNrNvNehH5qsMi0iGdJmSFKoQKBgQD4uYPYvm0fYThs0/PzKjKFtOxwdfaKPOGY3TLu
         * FJL+T0BfmY9AB6meDs0IcQsbx1BhxJ4fhr8cVldVbiXubZzxyxMD3DZq+nlOJV8Vvy+hj3cB6Gd+7tX1lt5eqEfKPh
         * yv8a9EyVNHjqOlD0EhC5E6Ome5uV9KGgsgwZwRTO1wtwKBgQCOnf43rSYIx9JZiuqAzNamE6yoJ7U3ihAt0+zcv0tOi
         * GDxpEaftMaoaP6u/E+KCModoEMegfBYJh1OnVUpWIe2S6GDqPpi4+aCDsl1HbyMEot/1+RiaJBONfClN8oKWd344JBb
         * ROROMhbfiwVLuRK8pQCNzWRufmV0kfzSXSGP+QKBgFUMysLwysuyKOM9zutVgJUr+rWyAK3gh5wH94Rl0KXZX7/Q+KU
         * CecOsd/vs+8lx7FCiNRe+sdb0x0RVN+9B2CruMABf6tPF9nj8WnlLOPRb5GvolotXDB7AiiWAEZxchN69HBu/ZBTR969
         * XegPcurpYgmOFucnTAf8fdUiNL5wdAoGAO8sn64Xv3VyR57LjcM7w675x9Cp5wuhisiQZOdAGLc3l/0nlxk3PwIoMxab
         * JXlEjFFq96UuHTh3kybITI3uXoqmA9SdimxV77mlus2idRYj87cPBYDUA05mv5EVIsyBMfW0BeRKgOdysVFsABGh635a
         * 6bbmAcwcRWFdgzX34dVkCgYAxMcpsZ+eWk3gSwVL/LFF4uy/ANheWngy7abqPWitWSYCc2dw6c0q5icLrWVl1FfaWoOE
         * s+wxL8sPEgTXgfMuNnZrJ8+TxnEf90CRFyYLA55L9QRL3Wfkrzax94uIDhsKT2zmRp1W4TBp9W4EMUlIKG1/bBofITI6t/a7p1R6CAg==
         */
        val privateStr = String(Base64.getEncoder().encode(privateKey.encoded))

        //密钥对每次重新生成的不同，所以要保存生成的字符串，使用时生成密钥对 对象
        val keyFactory = KeyFactory.getInstance("RSA")

        //生成私钥对象使用PKCS8EncodedKeySpec对象
        val genPrivateKey: PrivateKey =
            keyFactory.generatePrivate(PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateStr.toByteArray())))

        //公钥必须使用x.509格式
        val genPublicKey: PublicKey =
            keyFactory.generatePublic(X509EncodedKeySpec(Base64.getDecoder().decode(publicStr.toByteArray())))
    }

    //通过私钥加密
    fun encryptByPrivateKey(input: String): String {

        //1.创建cipher对象
        val cipher = Cipher.getInstance("RSA")

        //2.初始化cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, privateKey)

        //3.加密/解密
        val encryptArray = cipher.doFinal(input.toByteArray())

        return String(Base64.getEncoder().encode(encryptArray))
    }

    //通过公钥加密
    fun encryptByPublicKey(input: String): String {

        //1.创建cipher对象
        val cipher = Cipher.getInstance("RSA")

        //2.初始化cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)

        //3.加密/解密
        val encryptArray = cipher.doFinal(input.toByteArray())

        return String(Base64.getEncoder().encode(encryptArray))
    }

    //RSA分段加密：RSA加密速度慢，所以加密的文本长度不能超过117个字节，所以要对文本进行分段加密
    //RSA分段解密：解密的长度每次不能超过128
}


